﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint.Administration;
using System.Collections.ObjectModel;

namespace BlobCacheManager
{
    class BCManager
    {
        private bool enabledCheckBox;
        private int maxSize, maxAge;
        private string location, owner, path;
        private Guid webAppId;
        private const string ownerPrefix = "bramnuyts_blobcache";

        public BCManager(bool enabledCheckBox, int maxSize, string location, int maxAge, string path, string webAppId)
        {
            this.enabledCheckBox = enabledCheckBox;
            this.maxSize = maxSize;
            this.location = location;
            this.maxAge = maxAge;
            this.path = path;
            this.webAppId = new Guid(webAppId);
            this.owner = String.Format("{0}_{1}", ownerPrefix, webAppId.ToString());
        }

        public BCManager(string webAppId)
        {
            this.webAppId = new Guid(webAppId);
            this.owner = String.Format("{0}_{1}", ownerPrefix, webAppId.ToString());
        }

        public void UpdateChanges()
        {
            SPWebApplication webApplication = SPFarm.Local.GetObject(webAppId) as SPWebApplication;
            CleanUp(ref webApplication);

            // enabled or not
            SPWebConfigModification enabledMod = new SPWebConfigModification();
            enabledMod = generateModification("configuration/SharePoint/BlobCache", "enabled", enabledCheckBox.ToString());

            // put the max size
            SPWebConfigModification maxSizeMod = new SPWebConfigModification();
            maxSizeMod = generateModification("configuration/SharePoint/BlobCache", "maxSize", maxSize.ToString());

            // set the cache location
            SPWebConfigModification locationMod = new SPWebConfigModification();
            locationMod = generateModification("configuration/SharePoint/BlobCache", "location", location);

            // set the max age
            SPWebConfigModification maxAgeMod = new SPWebConfigModification();
            maxAgeMod = generateModification("configuration/SharePoint/BlobCache", "max-age", maxAge.ToString());

            // set the path
            SPWebConfigModification pathMod = new SPWebConfigModification();
            //wrap the path with the regex string
            string formatPath = "\\.({0})$";
            pathMod = generateModification("configuration/SharePoint/BlobCache", "path", string.Format(formatPath, path));

            // Apply the modification
            webApplication.WebConfigModifications.Add(enabledMod);
            webApplication.WebConfigModifications.Add(maxSizeMod);
            webApplication.WebConfigModifications.Add(locationMod);
            webApplication.WebConfigModifications.Add(maxAgeMod);
            webApplication.WebConfigModifications.Add(pathMod);
            webApplication.Update();
            webApplication.Farm.Services.GetValue<SPWebService>().ApplyWebConfigModifications();
        }

        private SPWebConfigModification generateModification(string path, string name, string value)
        {
            SPWebConfigModification webMod = new SPWebConfigModification();
            webMod.Path = path;
            webMod.Name = name;
            webMod.Value = value;
            webMod.Sequence = 0;
            webMod.Owner = owner;
            webMod.Type = SPWebConfigModification.SPWebConfigModificationType.EnsureAttribute;
            return webMod;
        }

        public Dictionary<string, string> GetCurrentMods()
        {
            SPWebApplication webApplication = SPFarm.Local.GetObject(webAppId) as SPWebApplication;
            Collection<SPWebConfigModification> modsCollection = webApplication.WebConfigModifications;

            // Clean up the previous mods
            Dictionary<string, string> modsDictionary = new Dictionary<string, string>();
            foreach (SPWebConfigModification mod in modsCollection)
            {
                if (mod.Owner.Equals(this.owner))
                {
                    modsDictionary.Add(mod.Name, mod.Value);
                }
            }
            return modsDictionary;
        }

        private void CleanUp(ref SPWebApplication webApplication)
        {
            Collection<SPWebConfigModification> modsCollection = webApplication.WebConfigModifications;

            // Clean up the previous mods
            int size = modsCollection.Count;
            bool pendingUpdate = false;
            for (int i = 0; i < size; i++)
            {
                if (modsCollection[0].Owner.Equals(owner))
                {
                    modsCollection.Remove(modsCollection[0]);
                    pendingUpdate = true;
                }
            }

            if (pendingUpdate)
                webApplication.Update();
        }

    }
}
